package com.rychlickikicior.kitijdb;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 *
 * @author kitikat
 */
public class Query {
    private String name;
    private QueryType type;
    private String content;
    private Map<String, Object> params = new LinkedHashMap<String, Object>();
    private List values;

    String getName() {
        return name;
    }

    void setName(String name) {
        this.name = name;
    }

    QueryType getType() {
        return type;
    }

    void setType(QueryType type) {
        this.type = type;
    }

    String getContent() {
        return content;
    }

    void setContent(String content) {
        this.params.clear();
        Pattern p = Pattern.compile(":[a-zA-Z0-9_]+");
        Matcher m = p.matcher(content);
        while (m.find())
            params.put(m.group().substring(1), "");
        this.content = content.replaceAll(":", ":__");
    }

    Map<String, Object> getParams() {
        return this.params;
    }

    Collection<String> getParameterNames() {
        return this.params.keySet();
    }

    void setParameter(String key, Object value) {
        this.params.put(key, value);
    }

    int getNthOccurence(String hayStack, int nth, String needle) {
        int i = 0, index = 0;
        while (i++ < nth)
            index = hayStack.indexOf(needle, index+1);
        return index;
    }


    String prepare() {
        String query = new String(this.content);
        String oldQuery = new String(this.content);
        Map<Integer, String> indexKey = new TreeMap<Integer, String>();
        this.values = new ArrayList();
        boolean changed = true;
        int iteration = 1;
        while (changed) {
            changed = false;
            for (String key : this.params.keySet()) {
                String newKey = ":__"+key;
                int index = query.indexOf(newKey);
                if (index > -1) {
                    changed = true;
                    query = query.replaceFirst(newKey, "?");
                    indexKey.put(this.getNthOccurence(oldQuery, iteration, newKey), key);
                }
            }
            iteration++;
        }
        for (Integer i : indexKey.keySet())
            this.values.add(this.params.get(indexKey.get(i)));
        for (String key : this.params.keySet())
            this.params.put(key, "");
        return query;
    }

    void fillValues(PreparedStatement p) {
        for (int i=0;i<values.size();i++)
            try {
                Object o = this.values.get(i);
                if (o instanceof java.util.Date) {
                    java.util.Date d = (java.util.Date)o;
                    p.setObject(i+1, new java.sql.Timestamp(d.getTime()));
                } else
                    p.setObject(i+1, o);
            } catch (SQLException se) { se.printStackTrace(); }
        this.values = null;
    }
}
